<?php

namespace app\admin\controller\financial;

use service\JsonService;
use app\common\model as M;

/**
 * 消费模块
 */
class Consume extends \app\admin\controller\financial\Order
{
	public $model = '\app\common\model\order\UserConsume';

    /**
     * [index description]
     * @return [type] [description]
     */
    public function checkout ()
    {
        return $this->fetch();
    }

    /**
     * 保存
     * 提交数据样例及说明
     * 每条数据必须有pck_id字段，如果大于0则说明是套餐，套餐数据必须包含packages数组
     * bought_id表示该条内容是否是用户已经购买的，如果用户未购买则还需加入到用户已购中形成一个新的订单
     * 如果全部为已购买的则只生成一个消费订单
    {
     "order_info":[
            {
                "pck_id":"0",
                "rel_type":"service",
                "rel_id":19,
                "qty":10,
                "price":19.9,
                "disc_amt":20,
                "bought_id":0,
                "max_nums":1
            },
            {
                "pck_id":"0",
                "rel_type":"goods",
                "rel_id":22,
                "qty":3,
                "price":19.9,
                "disc_amt":0,
                "bought_id":0,
                "max_nums":1
            },
            {
                "pck_id":"0",
                "rel_type":"goods",
                "rel_id":28,
                "qty":1,
                "price":19.9,
                "disc_amt":0,
                "bought_id":1,
                "max_nums":1
            },
            {
                "pck_id":"1",
                "bought_id":1,
                "max_nums":1,
                "price":19.9,
                "packages":[
                    {
                        "rel_type":"goods",
                        "rel_id":39,
                        "qty":3,
                        "max_nums":10
                    },
                    {
                        "rel_type":"goods",
                        "rel_id":28,
                        "qty":1,
                        "max_nums":10
                    }
                ]
            },
            {
                "pck_id":"2",
                "bought_id":0,
                "max_nums":1,
                "price":19.9,
                "packages":[
                    {
                        "rel_type":"service",
                        "rel_id":190,
                        "qty":3,
                        "max_nums":999
                    },
                    {
                        "rel_type":"goods",
                        "rel_id":328,
                        "qty":1,
                        "max_nums":999
                    }
                ]
            }
        ],
        "user_info":{
            "uid":2
        }
    }
     * @return   [type]           [description]
     */
    public function save ()
    {
        $data = $this->request->post();

        if ( !isset($data['order_info']) || !is_array($data['order_info']) ) return JsonService::fail('缺少订单信息');
        if ( !isset($data['user_info']) || !is_array($data['user_info']) ) return JsonService::fail('缺少用户信息');

        $res = \app\common\model\user\Bought::consumeOrPurcharse($data['order_info'] , $data['user_info']);

        if ( $res === false ) return JsonService::fail('结算失败【9901】');

        $this->model::beginTrans();
        try {
            $consume = $res['consume'];
            $consume['order_amt'] = $consume['orgn_amt'] - $consume['disc_amt'];
            $consume['uid']       = (int)$data['user_info']['uid'];
            $consume['pub_aid']   = $this->adminId;
            $consume['platform']  = M\Order::PTF_BACKEND;

            ## 创建订单
            $consume['items']       = $res['consume_items'];
            $consume['add_pcks']    = $res['add_pcks'];
            $consume['update_pcks'] = $res['update_pcks'];

            $order_id = $this->model::create_order($consume);
            if ( !$order_id ) {
                return JsonService::fail('创建订单失败【0981】');
            }

            $consume['order_id'] = $order_id;
            $this->model::commitTrans();
            return JsonService::successful('创建订单成功，请完成支付' , $consume);

        } catch ( \Exception $e ) {
            p($e);
            $this->model::rollbackTrans();
            return JsonService::fail($e->getMessage());
        }

        $this->model::rollbackTrans();
        return JsonService::fail('操作失败');


        ## 消费订单
        $consume = [
            'orgn_amt' => 0,
            'disc_amt' => 0
        ];

        ## 消费明细 - 需购买套餐 - 需购买服务/商品
        $consume_items = $add_packages = $add_services = [];

        foreach ( $data['order_info'] as &$item ) {
            $bought_id   = $item['bought_id'] ?? 0;

            $item['max_nums'] = $item['max_nums'] * $item['qty'];
            ## 如果已购，将单价和折扣金额重置为0
            if ( $bought_id > 0 ) {
                $item['price'] = $item['disc_amt'] = 0;
            }

            ## 套餐消费
            if ( isset($item['pck_id']) && $item['pck_id'] > 0 ) {
                $item_orgn            = bcmul($item['qty'] , $item['price'] , 2);
                $consume['orgn_amt'] += $item_orgn;
                $consume['disc_amt'] += $item['disc_amt'];

                $item_amt  = bcsub($item_orgn , $item['disc_amt'] , 2);

                $consume_items[] = [
                    'order_id' => 0,
                    'bought_id'=> $bought_id,
                    'pck_id'   => $item['pck_id'],
                    'rel_type' => 'package',
                    'rel_id'   => $item['pck_id'],
                    'rel_name' => $item['pck_name'] ?? '',
                    'price'    => $item['price'] * 1,
                    'qty'      => $item['qty'] * 1 ,
                    'disc_amt' => $item['disc_amt'] * 1,
                    'amt'      => $item_orgn - $item['disc_amt'],
                ];

                $pck_used_nums = 0;

                ## 单项计次记录子项目
                // if ( $item['valid_type'] == 1 ) {
                if ( !empty($item['packages']) ) {
                    /** 价格之所以默认为0由于是收的套餐的费用，子项不再重复计费 */
                    foreach ( $item['packages'] as $pkg_item ) {
                        $consume_items[] = [
                            'order_id' => 0,
                            'bought_id'=> $bought_id,
                            'pck_id'   => $item['pck_id'],
                            'rel_type' => $pkg_item['rel_type'],
                            'rel_id'   => $pkg_item['rel_id'],
                            'rel_name' => $pkg_item['rel_name'] ?? '',
                            'price'    => 0,
                            'qty'      => $pkg_item['qty'] * 1,
                            'disc_amt' => 0,
                            'amt'      => 0,
                        ];

                        $pck_used_nums += $pkg_item['qty'];
                    }
                }

                ## 整体计次和无限计次时重置为
                if ( $item['valid_type'] != 1 ) {
                    $pck_used_nums = $item['qty'];
                }

                ## 整体和不限次数直接记录套餐本身，不记录子项目
                // else {
                //     $consume_items[] = [
                //         'order_id' => 0,
                //         'bought_id'=> $bought_id,
                //         'pck_id'   => $item['pck_id'],
                //         'rel_type' => 'package',
                //         'rel_id'   => $item['pck_id'],
                //         'rel_name' => $item['pck_name'] ?? '',
                //         'price'    => $item['price'] * 1,
                //         'qty'      => $item['qty'] *1 ,
                //         'disc_amt' => 0,
                //         'amt'      => $item['price'] * 1,
                //     ];
                // }

                ## 如果未购买 先加入用户已购套餐
                if ( !$bought_id ) {
                    if ( $data['user_info']['uid'] > 0 ) {
                        $add_packages[] = [
                            'order_id'     => 0,
                            'uid'          => $data['user_info']['uid'],
                            'pck_id'       => $item['pck_id'],
                            'pck_name'     => $item['pck_name'] ?? '',
                            'bought_price' => $item_orgn - $item['disc_amt'],
                            'bought_qty'   => $item['qty'],
                            'create_time'  => date('Y-m-d H:i:s')
                        ];
                    }


                    ## 累加套餐价格
                    $consume['orgn_amt'] += ($item['price'] ?? 0);
                    $consume['disc_amt'] += ($item['disc_amt'] ?? 0);
                }

            } else {
                $consume_items[] = [
                    'order_id' => 0,
                    'bought_id'=> $bought_id,
                    'pck_id'   => 0,
                    'rel_type' => $item['rel_type'],
                    'rel_id'   => $item['rel_id'],
                    'rel_name' => $item['rel_name'] ?? '',
                    'price'    => $item['price'] * 1,
                    'qty'      => $item['qty'] *1 ,
                    'disc_amt' => $item['disc_amt'] * 1,
                    'amt'      => $item_amt * 1,
                ];
            }
        }

        $this->model::beginTrans();
        try {
            $consume['order_amt'] = $consume['orgn_amt'] - $consume['disc_amt'];
            $consume['uid']       = (int)$data['user_info']['uid'];
            $consume['pub_aid']   = $this->adminId;
            $consume['platform']  = M\Order::PTF_BACKEND;

            ## 创建订单
            $consume['items']     = $consume_items;
            $consume['package']   = $add_packages;

            $order_id = $this->model::create_order($consume);
            if ( !$order_id ) {
                return JsonService::fail('创建订单失败【0981】');
            }

            $consume['order_id'] = $order_id;
            $this->model::commitTrans();
            return JsonService::successful('创建订单成功，请完成支付' , $consume);
        } catch ( \Exception $e ) {
            p($e);
            $this->model::rollbackTrans();
            return JsonService::fail($e->getMessage());
        }

        $this->model::rollbackTrans();
        return JsonService::fail('操作失败');
    }

    /**
     * 选择已购套餐或服务（商品）时预检查
     * @Author   FW
     * @DateTime 2021-08-11
     * @Email    123763712@qq.com
     * @return   [type]           [description]
     */
    public function precheck ()
    {
        $bought_type = $this->request->post('bought_type' , 'package');
        $bought_id   = (int)$this->request->post('bought_id',0);
        $id          = (int)$this->request->post('id');

        if ( !$id ) return JsonService::fail('ID为空，请检查');

        try {
            if ( $bought_type == 'package' ) {
                $valid = M\Package::ConsumePrecheck($id , $bought_id);
            }

            if ( $bought_type == 'service' ) {
                $valid = M\Service::ConsumePrecheck($id , $bought_id);
            }

            if ( $bought_type == 'goods' ) {
                $valid = M\Goods::ConsumePrecheck($id , $bought_id);
            }

            if ( $valid && is_array($valid) ) {
                return JsonService::successful('SUCCESS' , $valid);
            }
        } catch ( \think\exception\ValidateException $e ) {
            return JsonService::fail($e->getError());
        }
        return JsonService::fail('FAIL');
    }

    /**
     * 订单作废
     * @param  [type] $id [description]
     * @return [type]     [description]
     */
    public function abolish ($id)
    {
        $order = M\Order::field('id,order_amt,order_type,pay_type,pay_status,uid,status')->where('id' , $id)->find();
        if ( empty($order) ) return JsonService::fail('订单不存在');

        if ( $order->status != 1 ) return JsonService::fail('订单无效，无法作废');

        $this->model::beginTrans();
        try {
            /** 01 作废订单 */
            $order->status           = M\Order::STATUS_ABOLISH;
            $order->last_update_time = date('Y-m-d H:i:s');
            $order->last_update_at   = $this->adminInfo['real_name'];
            $res  = $order->save();
            if ( $res === false ) throw new \Exception('操作失败【99011】');

            /** 02 会员消费 */
            if ( $order->uid > 0 ) {
                ## 02-01 检查消费明细中是否有已购的消费，如果有，还回用户已购记录中
                $boughts = M\OrderItems::where('order_id',$id)->where('bought_id','gt',0)->select();
                if ( !empty($boughts) ) {
                    $check = true;
                    foreach ( $boughts as $item ) {
                        ## 套餐
                        if ( $item['pck_id'] > 0 ) {
                            $package = M\Package::field('valid_type,valid_nums')->where('id' , $item['pck_id'])->find();

                            $decNums = 1;
                            /** 单项计次 */
                            if ( $package->valid_type == 1 ) {
                                $decNums = $item['qty'];
                            }

                            $res = M\BoughtPackage::where('id' , $item['bought_id'])->setDec('used_nums' , $decNums);
                            if ( $res === false ) {
                                $check = false;
                                break;
                            }
                        }
                        ## 服务或商品
                        else {
                            $res = M\BoughtService::where('id' , $item['bought_id'])->setDec('used_nums' , $item['qty']);
                            if ( $res === false ) {
                                $check = false;
                                break;
                            }
                        }
                    }

                    if ( $check === false ) throw new \Exception('操作失败【99012】');
                }

                ## 02-02 检查支付方式是否为余额支付，如果是，则需返回用户余额并记录财富变动
                if ( $order->pay_type == M\Order::PAY_BALANCE ) {
                    $user_bills = M\UserBill::field('type,amt')->where('order_id' , $id)->select();
                    if ( !empty($user_bills) ) {
                        $user = M\User::field('now_money,gift_money')->where('uid' , $order->uid)->find();

                        $check = true;
                        foreach ( $user_bills as $bill ) {
                            if ( $bill['type'] == 'now_money' ) {
                                // 消费类账单，amt是负数，此处用减法，负负得正
                                $user->now_money = $user->now_money - $bill['amt'];

                                $res = M\UserBill::insert([
                                   'uid'      =>    $order->uid,
                                   'order_id' =>    $order->id,
                                   'type'     =>    'now_money',
                                   'category' =>    $order->order_type,
                                   'title'    =>    '订单作废，退回账户',
                                   'amt'      =>    -$bill['amt'],
                                   'balance'  =>    $user->now_money,
                                   'add_time' =>    date('Y-m-d H:i:s'),
                                ]);
                                if ( $res === false ) {
                                    $check = false;
                                    break;
                                }

                                $res = $user->save();

                                if ( $res === false ) {
                                    $check = false;
                                    break;
                                }
                            }

                            if ( $bill['type'] == 'gift_money' ) {
                                // 消费类账单，amt是负数，此处用减法，负负得正
                                $user->gift_money = $user->gift_money - $bill['amt'];

                                $res = M\UserBill::insert([
                                   'uid'      =>    $order->uid,
                                   'order_id' =>    $order->id,
                                   'type'     =>    'gift_money',
                                   'category' =>    $order->order_type,
                                   'title'    =>    '订单作废，退回账户',
                                   'amt'      =>    -$bill['amt'],
                                   'balance'  =>    $user->gift_money,
                                   'add_time' =>    date('Y-m-d H:i:s'),
                                ]);
                                if ( $res === false ) {
                                    $check = false;
                                    break;
                                }

                                $res = $user->save();

                                if ( $res === false ) {
                                    $check = false;
                                    break;
                                }
                            }
                        }

                        if ( $check === false ) throw new \Exception('操作失败【99013】');
                    }
                }
            }

            $this->model::commitTrans();
            return JsonService::successful('订单已作废');
        } catch ( \Exception $e ) {
            $this->model::rollbackTrans();
            return JsonService::fail($e->getMessage());
        }

        $this->model::rollbackTrans();
        return JsonService::fail('操作失败');
    }
} //Class End